package com.swotxu.oldwebproject.session.listener.session;

import com.swotxu.oldwebproject.session.handler.SessionAttributeHandler;
import com.swotxu.oldwebproject.utils.SessionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpSessionEvent;
import java.util.Arrays;

/**
 * redis session 方法执行前后监听
 *
 * @Date: 2020/1/15 15:51
 * @Author: xu.hai
 */
public class RedisSessionAttributeListener implements HttpSessionMethodListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(RedisSessionAttributeListener.class);

    public static final String METHOD_ISNEW = "isNew";
    public static final String METHOD_INVALIDATE = "invalidate";
    public static final String METHOD_ISINVALID = "isInvalid";
    public static final String METHOD_REMOVEATTRIBUTE = "removeAttribute";
    public static final String METHOD_SETATTRIBUTE = "setAttribute";
    public static final String METHOD_GETATTRIBUTE = "getAttribute";

    @Override
    public void executeBefor(HttpSessionEvent event) {
        RedisSessionEvent rsEvent = (RedisSessionEvent) event;
        String sessionId = rsEvent.getSession().getId();
        String methodName = rsEvent.getMethod().getName();
        Object[] args = rsEvent.getArgs();
        LOGGER.debug("executeBefor -> methodName: {}, sessionId: {}, args: {}"
                , methodName, sessionId, Arrays.toString(args));
        switch (methodName) {
            case METHOD_GETATTRIBUTE:
                // 若调用 RedisSession 的 getAttribute 方法，则先检查 ThreadLocal 是否缓存，命中就设置中断并返回
                if (SessionAttributeHandler.hexists(sessionId, (String)args[0])) {
                    rsEvent.setInterrupte(true);
                    rsEvent.setResult(SessionAttributeHandler.hget(sessionId, (String)args[0]));
                }
                break;
            case METHOD_SETATTRIBUTE:
                // 若调用 RedisSession 的 setAttribute 方法，则先写入 ThreadLocal
                SessionAttributeHandler.hset(sessionId, (String)args[0], args[1]);
                // KEY_USERINFO 特殊处理
                if (!SessionUtil.KEY_USERINFO.equals(args[1])) {
                    rsEvent.setInterrupte(true);
                }
                break;
            case METHOD_ISNEW:
                // 若调用 RedisSession 的 isNew 方法，则先检查 ThreadLocal 是否缓存，命中就设置中断并返回
                if (SessionAttributeHandler.hexists(sessionId, METHOD_ISNEW)) {
                    rsEvent.setInterrupte(true);
                    rsEvent.setResult(SessionAttributeHandler.hget(sessionId, METHOD_ISNEW));
                }
                break;
        }

    }

    @Override
    public void executeAfter(HttpSessionEvent event) {
        RedisSessionEvent rsEvent = (RedisSessionEvent) event;
        String sessionId = rsEvent.getSession().getId();
        String methodName = rsEvent.getMethod().getName();
        Object[] args = rsEvent.getArgs();
        LOGGER.debug("executeAfter -> methodName: {}, sessionId: {}, args: {}"
                , methodName, sessionId, Arrays.toString(args));

        switch (methodName) {
            case METHOD_INVALIDATE:
                SessionAttributeHandler.removeAll();
                break;
            case METHOD_REMOVEATTRIBUTE:
                SessionAttributeHandler.removeField(sessionId, (String) args[0]);
                break;
            case METHOD_GETATTRIBUTE:
                SessionAttributeHandler.hset(sessionId, (String) args[0], rsEvent.getResult());
                break;
            case METHOD_ISNEW:
                SessionAttributeHandler.hset(sessionId, METHOD_ISNEW, rsEvent.getResult());
                break;
        }
    }
}
